﻿using System.Messaging;

namespace CppUT
{
    namespace Common
    {
        public enum CommunicationType
        {
            Receive,
            Transmit
        }

        public class TestDataCommunicator
        {
            public TestDataCommunicator(string aMessageQueueName, CommunicationType aCommunicationType)
            {
                Log.MethodEntry();
                _communicationType = aCommunicationType;
                if (!MessageQueue.Exists(aMessageQueueName))
                {
                    MessageQueue.Create(aMessageQueueName, false);
                }

                _messageQueue = new MessageQueue(aMessageQueueName, QueueAccessMode.SendAndReceive);

                //  Register a dedicated listening channel only if required, transmitting messages is considered as default.
                if (aCommunicationType == CommunicationType.Receive)
                {
                    _messageListener = new MessageListener(aMessageQueueName);
                    _messageListener.MessageReceived += MessageListenerMessageReceived;
                    _messageListener.Listen();
                }

                Log.MethodExit();
            }

            private void MessageListenerMessageReceived(Message message)
            {
                if (null != MessageAvailable)
                {
                    MessageAvailable(message);
                }
            }

            public void SendMessage(string messageName, object messageData)
            {
                Log.MethodEntry();

                var message = new Message { Label = messageName, Body = messageData};
                _messageQueue.Send(message);
                _messageQueue.Refresh();
                
                Log.MethodExit();
            }

            public void Close()
            {
                Log.MethodEntry();

                if (null != _messageListener)
                {
                    _messageListener.Stop();
                }

                Log.MethodExit();
            }

            private readonly MessageQueue _messageQueue;
            private readonly MessageListener _messageListener;
            private CommunicationType _communicationType;
            public delegate void MessageAvailableHandler(Message message);
            public event MessageAvailableHandler MessageAvailable;
        }
    }
}